package org.kernelab.basis.util;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.Writer;
import java.util.ArrayList;

import org.kernelab.basis.Filter;

public class CharacterFilter implements Runnable
{

	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		CharacterFilter filter = new CharacterFilter();
		filter.getFilters().add(new Filter<Character>() {

			public boolean filter(Character e)
			{
				return e == '\n';
			}

		});

		OutputStreamWriter writer = new OutputStreamWriter(System.out);
		filter.setReader(new StringReader("abc\nxyz\n123"));
		filter.setWriter(writer);
		filter.filter();
	}

	private Reader							reader;

	private Writer							writer;

	private ArrayList<Filter<Character>>	filters;

	private ArrayList<ActionListener>		progresses;

	public CharacterFilter()
	{
		this.setFilters(new ArrayList<Filter<Character>>());
		this.setProgresses(new ArrayList<ActionListener>());
	}

	public void filter()
	{
		if (this.getReader() != null && this.getWriter() != null) {
			try {
				if (this.getReader().ready()) {

					int i = 0;

					while ((i = this.getReader().read()) != -1) {

						char c = (char) i;

						for (ActionListener action : this.getProgresses()) {
							action.actionPerformed(new ActionEvent(this, i, ""));
						}

						for (Filter<Character> f : this.getFilters()) {
							if (!f.filter(c)) {
								this.getWriter().append(c);
								break;
							}
						}
					}

					this.getWriter().flush();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public ArrayList<Filter<Character>> getFilters()
	{
		return filters;
	}

	public ArrayList<ActionListener> getProgresses()
	{
		return progresses;
	}

	public Reader getReader()
	{
		return reader;
	}

	public Writer getWriter()
	{
		return writer;
	}

	public void run()
	{
		this.filter();
	}

	private void setFilters(ArrayList<Filter<Character>> filters)
	{
		this.filters = filters;
	}

	private void setProgresses(ArrayList<ActionListener> progresses)
	{
		this.progresses = progresses;
	}

	public void setReader(Reader reader)
	{
		this.reader = reader;
	}

	public void setWriter(Writer writer)
	{
		this.writer = writer;
	}

}
